package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.UserLikeApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.User;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.FriendVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserService {

    @Autowired
    private SmsTemplate template;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private UserFreezeService userFreezeService;

    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private MqMessageService mqMessageService;

    @DubboReference
    private UserApi userApi;
    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    /**
     * 发送短信验证码
     * @param phone
     */
    public void sendMsg(String phone) {
        //根据手机号查询用户，如果用户存在，查询是否被冻结
        User user = userApi.findByMobile(phone);
        if(user != null){
            userFreezeService.checkUserStatus("1",user.getId());
        }
        //1、随机生成6位数字
        //String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        //2、调用template对象，发送手机短信
        //template.sendSms(phone,code);
        //3、将验证码存入到redis
        redisTemplate.opsForValue().set("CHECK_CODE_"+phone,code, Duration.ofMinutes(5));
    }


    /**
     * 验证登录
     * @param phone
     * @param code
     */
    public Map loginVerification(String phone, String code) {
        //1、从redis中获取下发的验证码
        String redisCode = redisTemplate.opsForValue().get("CHECK_CODE_" + phone);
        //2、对验证码进行校验（验证码是否存在，是否和输入的验证码一致）
        if(StringUtils.isEmpty(redisCode) || !redisCode.equals(code)) {
            //验证码无效
            throw new BusinessException(ErrorResult.loginError());
        }
        //3、删除redis中的验证码
        redisTemplate.delete("CHECK_CODE_" + phone);
        //4、通过手机号码查询用户
        User user = userApi.findByMobile(phone);
        boolean isNew = false;
        //5、如果用户不存在，创建用户保存到数据库中
        String type="0101";//登录
        if(user == null) {
            type="0102";//注册
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long userId = userApi.save(user);
            user.setId(userId);
            isNew = true;

            //注册环信用户
            String hxUser="hx"+user.getId();
            Boolean create = huanXinTemplate.createUser(hxUser, Constants.INIT_PASSWORD);
            if(create){
                user.setHxUser(hxUser);
                user.setHxPassword(Constants.INIT_PASSWORD);
                userApi.update(user);
            }

        }

//        try{
//            Map map =new HashMap();
//            map.put("userId",user.getId().toString());
//            map.put("type",type);
//            map.put("logTime",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
//            String message = JSON.toJSONString(map);
//            amqpTemplate.convertAndSend("tanhua.log.exchange",
//                    "log.user",message);
//        }catch(Exception e){
//            e.printStackTrace();
//        }
        mqMessageService.sendLogMessage(user.getId(),type,"user",null);


        //6、通过JWT生成token(存入id和手机号码)
        Map tokenMap = new HashMap();
        tokenMap.put("id",user.getId());
        tokenMap.put("mobile",phone);
        String token = JwtUtils.getToken(tokenMap);
        //7、构造返回值
        Map retMap = new HashMap();
        retMap.put("token",token);
        retMap.put("isNew",isNew);

        return retMap;
    }


    /**
     * 检验验证码  --修改手机号
     */
    public Map checkCode(String phone,String code){
        //1、从redis中获取下发的验证码
        String redisCode = redisTemplate.opsForValue().get("CHECK_CODE_" + phone);

        //2、对验证码进行校验（验证码是否存在，是否和输入的验证码一致）
        if(StringUtils.isEmpty(redisCode) || !redisCode.equals(code)) {
           throw new BusinessException(ErrorResult.loginError());
        }
        //3、删除redis中的验证码
        redisTemplate.delete("CHECK_CODE_" + UserHolder.getMobile());
        Map map = new HashMap();
        map.put("verification", true);
        return map;

    }

    //保存手机号
    public void updatePhone(String phone) {
        User user =new User();
        user.setId(UserHolder.getUserId());
        user.setMobile(phone);
        userApi.updatePhone(user);
    }

    //互相喜欢，喜欢，粉丝数量的统计
    public Map counts() {
        Map map = userLikeApi.counts(UserHolder.getUserId());
        return map;
    }
    //查询互相喜欢/喜欢/粉丝 谁看过我 -列表
    public PageResult list(String type, int page, int pagesize) {
        if("1".equals(type)){
            List<UserLike> list=userLikeApi.findEachLike(UserHolder.getUserId());
            if(CollUtil.isEmpty(list)){
                return new PageResult();
            }
            List<Long> userIds =CollUtil.getFieldValues(list,"userId",Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds,null);
            List<FriendVo> voList=new ArrayList<>();
            for (UserLike like : list) {
                UserInfo userInfo=map.get(like.getUserId());
                if(userInfo!=null){
                    FriendVo vo =new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    vo.setAlreadyLove(true);
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("2".equals(type)){
            List<UserLike> userLikes = userLikeApi.getUserLikes(UserHolder.getUserId());
            if (CollUtil.isEmpty(userLikes)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(userLikes, "likeUserId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (UserLike like : userLikes) {
                UserInfo userInfo = map.get(like.getLikeUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    vo.setAlreadyLove(true);
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("3".equals(type)){
            List<UserLike> likeMeUsers = userLikeApi.getLikeMeUser(UserHolder.getUserId());
            if (CollUtil.isEmpty(likeMeUsers)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(likeMeUsers, "userId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (UserLike like : likeMeUsers) {
                UserInfo userInfo = map.get(like.getUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    //查询我是否也喜欢了当前用户
                    Boolean flag = userLikeApi.likeOrNot(UserHolder.getUserId(),like.getUserId());
                    if (flag){
                        vo.setAlreadyLove(true);
                    }else {
                        vo.setAlreadyLove(false);
                    }
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("4".equals(type)){
            List<Visitors> list = visitorsApi.queryAllVisitorsList(UserHolder.getUserId());
            if (CollUtil.isEmpty(list)){
                return  new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (Visitors visitors : list) {
                UserInfo userInfo = map.get(visitors.getVisitorUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    //查询当前操作用户是否也喜欢了指定用户
                    Boolean flag = userLikeApi.likeOrNot(UserHolder.getUserId(),visitors.getVisitorUserId());
                    if (flag){
                        vo.setAlreadyLove(true);
                    }else {
                        vo.setAlreadyLove(false);
                    }
                    voList.add(vo);
                }
            }
            String key = Constants.VISITORS_USER;
            String hashKey = UserHolder.getUserId().toString();
            String value = String.valueOf(System.currentTimeMillis());
            redisTemplate.opsForHash().put(key,hashKey,value);
            return new PageResult(page,pagesize,0L,voList);
        }else {
            throw new BusinessException(ErrorResult.error());
        }
    }
}
